package com.tsugun.mediaplayer.view.widget

import android.animation.Animator
import android.animation.TimeInterpolator
import android.animation.ValueAnimator
import android.content.Context
import android.support.v4.content.ContextCompat
import android.support.v7.widget.Toolbar
import android.util.AttributeSet
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import android.widget.*
import com.tsugun.mediaplayer.R
import org.jetbrains.anko.*

/**
 * 自定义滑动变形的 view
 * Created by shize on 2017/8/29.
 */
class SlidingDeformation @JvmOverloads constructor(
        context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
        RelativeLayout(context, attrs, defStyleAttr), GestureDetector.OnGestureListener {
    // views
    private lateinit var mContent: View // content
    private var mHeight = 0 // content 控件高度
    private var mMinHeight = 0  // content 缩小时的高度
    private var mWidth = 0 // content 控件宽度
    private var mScrollScale = 0f // content 滑动完成比例

    private lateinit var mBgColor:View // 背景色

    private lateinit var mAlbumIcon: ImageView // 专辑图片
    private var mAlbumScale = 0f // 专辑图片与滑动间距的比例

    private lateinit var mTitleText: TextView // 歌曲标题
    private var mTitleLeftScale = 0f // 标题左间距与滑动间距的比例
    private var mTitleTopScale = 0f // 标题上间距与滑动间距的比例
    private var mTitleMaxMargin = 0 // 标题最大 margin

    private lateinit var mArtistText: TextView // 歌手名称
    private var mArtistLeftScale = 0f // 歌手左间距与滑动间距的比例
    private var mArtistMaxMargin = 0 // 歌手最大 margin

    private lateinit var mLyricText: TextView // 歌词

    private lateinit var mPlayBtn: ImageButton // 播放按钮
    private var maxPlayLeft: Int = 0 // 播放按钮最大左间距
    private var mButtonBottomMargin: Float = 0f // button相对于底部的间距
    private var buttonBox: Int = 0 // 每个按钮平均分配到的宽度
    private var buttonLeftMargin: Int = 0 // 按钮在分配到的宽度内的左间距

    private lateinit var mNextBtn: ImageButton // 下一首按钮
    private var maxNextLeft: Int = 0 // 下一首最大左间距

    private lateinit var mPrevBtn: ImageButton // 上一首按钮
    private var maxPrevLeft: Int = 0 // 上一首最大左间距

    private lateinit var mFavorite: ImageButton // 最爱按钮
    private var maxFavoriteLeft: Int = 0 // 最爱按钮最大左间距

    private lateinit var mPlayList: ImageButton // 播放列表按钮
    private lateinit var mToolbar: Toolbar // 工具栏
    private lateinit var mSeekBar: SeekBar // 进度条
    private lateinit var mCurrentTime: TextView // 当前进度时间显示
    private lateinit var mTotalTime: TextView // 总进度时间显示

    var mOnSlidingView: OnSlidingView? = null // 事件监听
    var isOpen: Boolean = false // 是否展开
    private var mLastY = 0 // 上一次触摸的 Y 轴的坐标
    private var mScreensHeight: Int = 0 // 屏幕高度
    private var mScreensWidth: Int = 0 // 屏幕宽度

    private var mGestureDetector: GestureDetector = GestureDetector(context, this) // 手势检测器

    override fun onFinishInflate() {
        super.onFinishInflate()
        initAllChildViews()
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        if (mWidth == 0) {
            recordParameter()
            layoutMiniBarUI()
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        calculateScale()
    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        if (event!!.action == MotionEvent.ACTION_UP) {
            doAnimation(getTargetPosition())
            if (mOnSlidingView != null) {
                mOnSlidingView!!.onTouchUp()
            }
        }
        return mGestureDetector.onTouchEvent(event)
    }

    /**
     * 主动关闭
     */
    fun doClose() {
        if (!isOpen) {
            return
        }
        mScrollScale = 1f
        invisibleToolbar()
        doAnimation(0f)
    }

    /**
     * 判断为 open
     */
    private fun open() {
        isOpen = true
        visibleToolbar()
        layoutPlayerUI()
    }

    /**
     * 判断为 close
     */
    private fun close() {
        isOpen = false
        layoutMiniBarUI()
    }

    override fun onShowPress(p0: MotionEvent?) {

    }

    override fun onSingleTapUp(p0: MotionEvent?): Boolean {
        return false
    }

    override fun onDown(p0: MotionEvent?): Boolean {
        if (mOnSlidingView != null) {
            mOnSlidingView!!.onTouchDown()
        }
        // 判断滑动是否为 content
        if (p0!!.y < mScreensHeight - mHeight) {
            return false
        }
        mLastY = p0.y.toInt()
        return true
    }

    override fun onFling(p0: MotionEvent?, p1: MotionEvent?, p2: Float, p3: Float): Boolean {
        return false
    }

    override fun onLongPress(p0: MotionEvent?) {

    }

    override fun onScroll(firstEvent: MotionEvent?, newEvent: MotionEvent?, px: Float, py: Float): Boolean {
        invisibleToolbar()
        // 设置 content
        layoutContent(newEvent!!.y)
        // 记录这次的手指 Y 轴位置
        mLastY = newEvent.y.toInt()
        return true
    }

    /**
     * 执行动画
     */
    private fun doAnimation(tag: Float) {
        val top = mScreensHeight - mMinHeight
        val animator = ValueAnimator.ofFloat(mScrollScale, tag)
        animator.duration = getAnimationDuration()
        animator.interpolator = DecelerateInterpolator(1f) as TimeInterpolator?
        animator.addUpdateListener { animator ->
            val value: Float = animator.animatedValue as Float
            mScrollScale = value
            autoContent(value, top)
        }
        animator.addListener(object : Animator.AnimatorListener {
            override fun onAnimationRepeat(p0: Animator?) {}

            override fun onAnimationEnd(p0: Animator?) {
                judgeState()
                if (mOnSlidingView != null) {
                    mOnSlidingView!!.endAnimation()
                }
            }

            override fun onAnimationCancel(p0: Animator?) {}

            override fun onAnimationStart(p0: Animator?) {
                if (mOnSlidingView != null) {
                    mOnSlidingView!!.startAnimation()
                }
            }

        })
        animator.start()
    }

    /**
     * 获取动画执行实际时长
     */
    private fun getAnimationDuration(): Long {
        // 实际执行动画时长
        val doAnimationTime: Long
        if (isOpen) {
            doAnimationTime = (ANIMATION_TOTAL_DURATION * mScrollScale).toLong()
        } else {
            doAnimationTime = (ANIMATION_TOTAL_DURATION * (1 - mScrollScale)).toLong()
        }
        return doAnimationTime
    }

    /**
     * 获取目标值
     */
    private fun getTargetPosition(): Float {
        val tag: Float
        if (isOpen) {
            if (mScrollScale <= 1 - JUDGE_SWITCH_VALUE) {
                tag = 0f
            } else {
                tag = 1f
            }
        } else {
            if (mScrollScale == 0f) {
                // 点击迷你播放条
                tag = 1f
                return tag
            }
            if (mScrollScale >= JUDGE_SWITCH_VALUE) {
                tag = 1f
            } else {
                tag = 0f
            }
        }
        return tag
    }

    /**
     * 判断状态
     */
    private fun judgeState() {
        if (mScrollScale == 1f) {
            open()
        }
        if (mScrollScale == 0f) {
            close()
        }
    }

    /**
     * 设置 content
     */
    private fun layoutContent(y: Float) {
        // 计算手指滑动的距离，再计算 content 与顶部的间距
        var top = mScreensHeight - mHeight + (y - mLastY)
        // 检测是否到达边界
        top = checkEdge(top)
        // 计算滑动百分比
        mScrollScale = 1 - (top / (mScreensHeight - mMinHeight))
        // 通过 layout 移动 content
        mContent.layout(0, top.toInt(), mWidth, mScreensHeight)
        // 更新 content 的高度
        mHeight = mContent.height
        mBgColor.layout(0, 0, mWidth, mHeight)
        // 设置文字
        layoutControl(top.toInt())
    }

    /**
     * 检测是否到达边界
     */
    private fun checkEdge(top: Float): Float {
        var top1 = top
        if (top1 < 0) {
            top1 = 0f
        }
        if (top1 > mScreensHeight - mMinHeight) {
            top1 = mScreensHeight - mMinHeight.toFloat()
        }
        return top1
    }

    /**
     * 自动设置 content
     */
    private fun autoContent(nowY: Float, total: Int) {
        val top = (1 - nowY) * total
        mContent.layout(0, top.toInt(), mWidth, mScreensHeight)
        mHeight = mContent.height
        mBgColor.layout(0, 0, mWidth, mHeight)
        layoutControl(top.toInt())
    }

    /**
     * 设置标题文字
     */
    private fun layoutControl(top: Int) {
        // 标题
        val titleLeftMargin = mTitleMaxMargin - (top * mTitleLeftScale).toInt()
        val titleTopMargin = mWidth - (top * mTitleTopScale).toInt()
        mTitleText.layout(titleLeftMargin, titleTopMargin, titleLeftMargin + mTitleText.width,
                titleTopMargin + mTitleText.height)
        // 歌手
        val artistLeftMargin = mArtistMaxMargin - (top * mArtistLeftScale).toInt()
        val artistTopMargin = titleTopMargin + mTitleText.height
        mArtistText.layout(artistLeftMargin, artistTopMargin, artistLeftMargin + mArtistText.width,
                artistTopMargin + mArtistText.height)
        // 歌词
        val lyricTopMargin = titleTopMargin + (mTitleText.height * LYRIC_TOP_SCALE_OF_TITLE_HEIGHT).toInt()
        mLyricText.layout(0, lyricTopMargin, mWidth, lyricTopMargin + mLyricText.height)
        // 设置按钮位置
        layoutButton()
        // 设置进度条的位置
        layoutSeekBar()
        // 设置图片的位置
        layoutAlbumIcon(top)
    }

    /**
     * 设置专辑图片
     */
    private fun layoutAlbumIcon(top: Int) {
        val albumMargin = mWidth - (top * mAlbumScale).toInt()
        mAlbumIcon.layout(0, 0, albumMargin, albumMargin)
    }

    /**
     * 设置进度条
     */
    private fun layoutSeekBar() {
        mSeekBar.layout(0, mHeight - mSeekBar.height, mWidth, mHeight)
        val topMargin = mScreensHeight - mSeekBar.height
        mCurrentTime.layout(0, topMargin - mCurrentTime.height, mCurrentTime.width, topMargin)
        mTotalTime.layout(mWidth - mTotalTime.width, topMargin - mCurrentTime.height, mWidth, topMargin)
    }

    /**
     * 设置按钮位置
     */
    private fun layoutButton() {
        // 播放列表按钮
        val playListTopMargin = mHeight - ((mButtonBottomMargin + mPlayList.height) * mScrollScale).toInt()
        val playListLeftMargin = mWidth - ((mWidth - (buttonLeftMargin + (buttonBox * 4))) * mScrollScale).toInt()
        // 下一首按钮
        val nextTopMargin = mHeight - (mButtonBottomMargin * mScrollScale + mPlayBtn.height).toInt()
        val nextLeftMargin = maxNextLeft - ((maxNextLeft - (buttonLeftMargin + (buttonBox * 3))) * mScrollScale).toInt()
        // 播放按钮
        val playLeftMargin = maxPlayLeft - ((maxPlayLeft - (buttonLeftMargin + (buttonBox * 2))) * mScrollScale).toInt()
        // 上一首按钮
        val prevLeftMargin = maxPrevLeft - ((maxPrevLeft - (buttonLeftMargin + buttonBox)) * mScrollScale).toInt()
        // 喜欢按钮
        val favoriteLeftMargin = maxFavoriteLeft - ((maxFavoriteLeft - buttonLeftMargin) * mScrollScale).toInt()

        mPlayList.layout(playListLeftMargin, playListTopMargin, playListLeftMargin + mPlayList.width,
                playListTopMargin + mPlayList.height)
        mNextBtn.layout(nextLeftMargin, nextTopMargin, nextLeftMargin + mNextBtn.width,
                nextTopMargin + mNextBtn.height)
        mPlayBtn.layout(playLeftMargin, nextTopMargin, playLeftMargin + mNextBtn.width,
                nextTopMargin + mPlayBtn.height)
        mPrevBtn.layout(prevLeftMargin, playListTopMargin, prevLeftMargin + mPrevBtn.width,
                playListTopMargin + mPrevBtn.height)
        mFavorite.layout(favoriteLeftMargin, playListTopMargin, favoriteLeftMargin + mFavorite.width,
                playListTopMargin + mFavorite.height)
    }

    /**
     * 记录参数
     */
    private fun recordParameter() {
        // 获取content的高
        mHeight = mContent.height
        mMinHeight = mContent.height
        mWidth = mContent.width
        // 测量屏幕
        mScreensHeight = height
        mScreensWidth = width
        mToolbar.visibility = View.INVISIBLE
        // 获取最大滑动距离
        val topMargin = mScreensHeight - mMinHeight.toFloat()
        // 专辑图片比例
        mAlbumScale = (mWidth - mAlbumIcon.width) / topMargin

        calculateScale()

        mButtonBottomMargin = mPlayBtn.height / BUTTON_TOP_MARGIN_OF_HEIGHT
        buttonBox = mWidth / 5
        buttonLeftMargin = (buttonBox - mFavorite.width) / 2
        maxNextLeft = mWidth - mNextBtn.width
        maxPlayLeft = mWidth - (mPlayBtn.width * 2)
        maxPrevLeft = mWidth - (mPrevBtn.width * 3)
        maxFavoriteLeft = mWidth - (mFavorite.width * 4)
    }

    /**
     * 计算子控件与需要滑动间距的比例
     */
    private fun calculateScale() {
        // 获取最大滑动距离
        val topMargin = mScreensHeight - mMinHeight.toFloat()
        // 标题间距比例
        mTitleMaxMargin = (mWidth - mTitleText.width) / 2
        mTitleLeftScale = (mTitleMaxMargin - mMinHeight) / topMargin
        mTitleTopScale = mWidth / topMargin
        // 歌手间距比例
        mArtistMaxMargin = (mWidth - mArtistText.width) / 2
        mArtistLeftScale = (mArtistMaxMargin - mMinHeight) / topMargin
    }

    /**
     * 隐藏 Toolbar
     */
    private fun invisibleToolbar() {
        mToolbar.layout(0, -mToolbar.height, mToolbar.width, 0)
        mToolbar.visibility = View.INVISIBLE
    }

    /**
     * 显示 Toolbar
     */
    private fun visibleToolbar() {
        mToolbar.layout(0, 0, mToolbar.width, mToolbar.height)
        mToolbar.visibility = View.VISIBLE
    }

    /**
     * 展开后的播放界面
     */
    private fun layoutPlayerUI() {
        val lpContent = mContent.layoutParams as RelativeLayout.LayoutParams
        lpContent.height = mContent.height
        lpContent.width = mContent.width

        val lpToolbar = mToolbar.layoutParams as RelativeLayout.LayoutParams
        lpToolbar.topMargin = (-mToolbar.height * (1 - mScrollScale)).toInt()

        val lpAlbum = mAlbumIcon.layoutParams as RelativeLayout.LayoutParams
        lpAlbum.height = mAlbumIcon.height
        lpAlbum.width = mAlbumIcon.width

        val lpTitle = mTitleText.layoutParams as RelativeLayout.LayoutParams
        lpTitle.topMargin = mWidth
        lpTitle.centerHorizontally()

        val lpArtist = mArtistText.layoutParams as RelativeLayout.LayoutParams
        lpArtist.centerHorizontally()
        lpArtist.below(mTitleText)

        val lpLyric = mLyricText.layoutParams as RelativeLayout.LayoutParams
        lpLyric.topMargin = (mTitleText.height * LYRIC_TOP_SCALE_OF_TITLE_HEIGHT).toInt()
        lpLyric.below(mAlbumIcon)

        val lpFavorite = mFavorite.layoutParams as RelativeLayout.LayoutParams
        val buttonTopMargin = (mHeight - mFavorite.height - mButtonBottomMargin).toInt()
        lpFavorite.leftMargin = buttonLeftMargin
        lpFavorite.topMargin = buttonTopMargin
        lpFavorite.removeRule(BELOW)

        val lpPrev = mPrevBtn.layoutParams as RelativeLayout.LayoutParams
        lpPrev.leftMargin = buttonLeftMargin + buttonBox
        lpPrev.topMargin = buttonTopMargin
        lpPrev.removeRule(BELOW)

        val lpPlay = mPlayBtn.layoutParams as RelativeLayout.LayoutParams
        lpPlay.leftMargin = buttonLeftMargin + (buttonBox * 2)
        lpPlay.topMargin = buttonTopMargin
        lpPlay.removeRule(ALIGN_PARENT_END)

        val lpNext = mNextBtn.layoutParams as RelativeLayout.LayoutParams
        lpNext.leftMargin = buttonLeftMargin + (buttonBox * 3)
        lpNext.topMargin = buttonTopMargin
        lpNext.removeRule(ALIGN_PARENT_END)

        val lpPlayList = mPlayList.layoutParams as RelativeLayout.LayoutParams
        lpPlayList.leftMargin = buttonLeftMargin + (buttonBox * 4)
        lpPlayList.topMargin = buttonTopMargin
        lpPlayList.removeRule(BELOW)
        lpPlayList.removeRule(RIGHT_OF)

        val lpCurrent = mCurrentTime.layoutParams as RelativeLayout.LayoutParams
        lpCurrent.bottomMargin = mSeekBar.height
        lpCurrent.alignParentBottom()

        val lpTotal = mTotalTime.layoutParams as RelativeLayout.LayoutParams
        lpTotal.bottomMargin = mSeekBar.height
        lpTotal.alignParentEnd()
        lpTotal.alignParentBottom()

        val lpSeekBar = mSeekBar.layoutParams as RelativeLayout.LayoutParams
        mSeekBar.isEnabled = true

        mContent.layoutParams = lpContent
        mToolbar.layoutParams = lpToolbar
        mAlbumIcon.layoutParams = lpAlbum
        mTitleText.layoutParams = lpTitle
        mArtistText.layoutParams = lpArtist
        mLyricText.layoutParams = lpLyric
        mFavorite.layoutParams = lpFavorite
        mPrevBtn.layoutParams = lpPrev
        mPlayBtn.layoutParams = lpPlay
        mNextBtn.layoutParams = lpNext
        mPlayList.layoutParams = lpPlayList
        mCurrentTime.layoutParams = lpCurrent
        mTotalTime.layoutParams = lpTotal
        mSeekBar.layoutParams = lpSeekBar
    }

    /**
     * 布局初始位置 -> 缩小后的迷你播放条
     */
    private fun layoutMiniBarUI() {
        val lpContent = mContent.layoutParams as RelativeLayout.LayoutParams
        lpContent.height = mContent.height
        lpContent.width = mContent.width

        val lpToolbar = mToolbar.layoutParams as RelativeLayout.LayoutParams
        lpToolbar.topMargin = (-mToolbar.height * (1 - mScrollScale)).toInt()

        val lpAlbum = mAlbumIcon.layoutParams as RelativeLayout.LayoutParams
        lpAlbum.height = mAlbumIcon.height
        lpAlbum.width = mAlbumIcon.width

        val lpTitle = mTitleText.layoutParams as RelativeLayout.LayoutParams
        lpTitle.leftMargin = mHeight
        lpTitle.topMargin = 0
        lpTitle.removeRule(CENTER_HORIZONTAL)

        val lpArtist = mArtistText.layoutParams as RelativeLayout.LayoutParams
        lpArtist.leftMargin = mHeight
        lpArtist.removeRule(CENTER_HORIZONTAL)
        lpArtist.below(mTitleText)

        val lpLyric = mLyricText.layoutParams as RelativeLayout.LayoutParams
        lpLyric.topMargin = (mTitleText.height * LYRIC_TOP_SCALE_OF_TITLE_HEIGHT).toInt()
        lpLyric.below(mAlbumIcon)

        val lpFavorite = mFavorite.layoutParams as RelativeLayout.LayoutParams
        lpFavorite.leftMargin = maxFavoriteLeft
        lpFavorite.topMargin = mHeight
        lpFavorite.below(mArtistText)

        val lpPrev = mPrevBtn.layoutParams as RelativeLayout.LayoutParams
        lpPrev.leftMargin = maxPrevLeft
        lpPrev.topMargin = mHeight
        lpPrev.below(mArtistText)

        val lpPlay = mPlayBtn.layoutParams as RelativeLayout.LayoutParams
        lpPlay.leftMargin = maxPlayLeft
        lpPlay.topMargin = 0

        val lpNext = mNextBtn.layoutParams as RelativeLayout.LayoutParams
        lpNext.leftMargin = maxNextLeft
        lpNext.topMargin = 0

        val lpPlayList = mPlayList.layoutParams as RelativeLayout.LayoutParams
        lpPlayList.leftMargin = mWidth
        lpPlayList.topMargin = mHeight
        lpPlayList.below(mArtistText)
        lpPlayList.rightOf(mNextBtn)

        val lpCurrent = mCurrentTime.layoutParams as RelativeLayout.LayoutParams
        lpCurrent.bottomMargin = -mCurrentTime.height
        lpCurrent.alignParentBottom()

        val lpTotal = mTotalTime.layoutParams as RelativeLayout.LayoutParams
        lpTotal.bottomMargin = -mTotalTime.height
        lpTotal.alignParentEnd()
        lpTotal.alignParentBottom()

        val lpSeekBar = mSeekBar.layoutParams as RelativeLayout.LayoutParams
        mSeekBar.isEnabled = false

        mContent.layoutParams = lpContent
        mToolbar.layoutParams = lpToolbar
        mAlbumIcon.layoutParams = lpAlbum
        mTitleText.layoutParams = lpTitle
        mArtistText.layoutParams = lpArtist
        mLyricText.layoutParams = lpLyric
        mFavorite.layoutParams = lpFavorite
        mPrevBtn.layoutParams = lpPrev
        mPlayBtn.layoutParams = lpPlay
        mNextBtn.layoutParams = lpNext
        mPlayList.layoutParams = lpPlayList
        mCurrentTime.layoutParams = lpCurrent
        mTotalTime.layoutParams = lpTotal
        mSeekBar.layoutParams = lpSeekBar
    }

    /**
     * 初始化所有控件
     */
    private fun initAllChildViews() {
        mContent = findViewById(R.id.id_content)
        mBgColor = findViewById(R.id.id_back_color)
        mAlbumIcon = findViewById(R.id.id_player_album_image) as ImageView
        mTitleText = findViewById(R.id.id_player_title) as TextView
        mArtistText = findViewById(R.id.id_player_sub_title) as TextView
        mLyricText = findViewById(R.id.id_player_lyric) as TextView
        mPlayBtn = findViewById(R.id.id_player_action) as ImageButton
        mNextBtn = findViewById(R.id.id_player_next) as ImageButton
        mPrevBtn = findViewById(R.id.id_player_previous) as ImageButton
        mFavorite = findViewById(R.id.id_player_favorite) as ImageButton
        mPlayList = findViewById(R.id.id_player_mode) as ImageButton
        mToolbar = findViewById(R.id.id_player_toolbar) as Toolbar
        mSeekBar = findViewById(R.id.id_player_seek_bar) as SeekBar
        mCurrentTime = findViewById(R.id.id_player_timer_left) as TextView
        mTotalTime = findViewById(R.id.id_player_timer_right) as TextView
    }

    /**
     * 从dp转换为px

     * @param dipValue dp值
     * @return px值
     */
    private fun dipToPx(dipValue: Float): Float {
        // 获取比例
        val scale = context.resources.displayMetrics.density
        return dipValue * scale + 0.5f
    }

    /**
     * 从px转换为dp

     * @param pxValue px值
     * @return dp值
     */
    private fun pxToDip(pxValue: Float): Float {
        // 获取比例
        val scale = context.resources.displayMetrics.density
        return pxValue / scale + 0.5f
    }

    companion object {
        val TAG = "SlidingDeformation"
        val ANIMATION_TOTAL_DURATION = 300L // 动画执行总时长
        val JUDGE_SWITCH_VALUE = 0.2f // 判断滑动多少百分比为有效滑动
        val LYRIC_TOP_SCALE_OF_TITLE_HEIGHT = 2.8 // 歌词顶部间距相对于标题高度的倍数
        val BUTTON_TOP_MARGIN_OF_HEIGHT = 2.4f // 按钮底部间距相对于自身高度的倍数
    }

    /**
     * 控件监听接口
     */
    interface OnSlidingView {
        fun onTouchDown()
        fun onTouchUp()
        fun startAnimation()
        fun endAnimation()
    }
}